package cn.exrick.xboot.common.aop;

import cn.exrick.xboot.common.annotation.SystemLog;
import cn.exrick.xboot.common.constant.CommonConstant;
import cn.exrick.xboot.common.utils.IpInfoUtil;
import cn.exrick.xboot.common.utils.ObjectUtil;
import cn.exrick.xboot.common.utils.ResultUtil;
import cn.exrick.xboot.common.utils.ThreadPoolUtil;
import cn.exrick.xboot.modules.base.entity.Log;
import cn.exrick.xboot.modules.base.entity.elasticsearch.EsLog;
import cn.exrick.xboot.modules.base.service.LogService;
import cn.exrick.xboot.modules.base.service.elasticsearch.EsLogService;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.NamedThreadLocal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Spring AOP
 *
 * @author Exrickx
 */
@Aspect
@Component
@Slf4j
public class AdminInterceptAspect {


    @Value("${AdminIntercept.flag}")
    private Boolean flag;

    @Autowired(required = false)
    private HttpServletRequest request;

    @Autowired
    private IpInfoUtil ipInfoUtil;

    private String requestURI;


    /**
     * Controller层切点,注解方式
     */
    //@Pointcut("execution(* *..controller..*Controller*.*(..))")
    @Pointcut("@annotation(cn.exrick.xboot.common.annotation.AdminIntercept)")
    public void controllerAspect() {
    }

    /**
     * 通知 (在方法执行之前返回)用于拦截Controller层对超级管理员进行操作的接口
     * 主要拦截
     *
     * @param
     * @throws Throwable
     */
    @Around("controllerAspect()")
    public Object doBefore(ProceedingJoinPoint pjp) throws Throwable {
        if (flag) {
            requestURI = request.getRequestURI();
            log.info("访问的url" + request.getRequestURI());
            //限制修改信息接口
          /*  if (CommonConstant.METHOD_UPDATE_INFO.equals(requestURI)) {
                Map<String, String[]> params = request.getParameterMap();
                String s = ObjectUtil.mapToString(params);
                for (Map.Entry<String, String[]> m : params.entrySet()) {
                    //System.out.println("key:" + m.getKey() );
                    if ("id".equals(m.getKey())) {
                        for (int i = 0; i < m.getValue().length; i++) {
                            String[] value = m.getValue();
                            if (CommonConstant.PARAM_ID.equals(value[i])) {
                                System.out.println("请求参数" + s);
                                return new ResultUtil<Object>().setErrorMsg("禁止修改超级管理员信息");
                            }

                        }
                    }

                }

            }*/


            /**
             * 提高效率
             * if语句每次都需要判断，而switch则只判断一次
             */
            switch (requestURI) {
                case CommonConstant.METHOD_UPDATE_INFO:
                    log.info("筛选信息修改接口：" + CommonConstant.METHOD_UPDATE_INFO);
                    return interceptUserUpdate(pjp);
                case CommonConstant.METHOD_UPDATEROLE_INFO:
                    log.info("筛选Role信息修改接口：" + CommonConstant.METHOD_UPDATEROLE_INFO);
                    return interceptRoleUpdate(pjp);
                case CommonConstant.METHOD_ADDUSER_INFO:
                    log.info("筛选添加user接口：" + CommonConstant.METHOD_ADDUSER_INFO);
                    return interceptUserAdd(pjp);
            }

            //处理特殊的筛选
            if (interceptContainsURI(pjp, requestURI, CommonConstant.METHOD_DELETE_INFO)) {
                System.out.println("特殊处理在url中传值的请求：删除user");
                return interceptUserDeleteJudge(pjp);
            }
            if (interceptContainsURI(pjp, requestURI, CommonConstant.METHOD_DELETEROLE_INFO)) {
                System.out.println("特殊处理在url中传值的请求:删除角色");
                return interceptRoleDeleteJudge(pjp);
            }
        }
        return pjp.proceed();
    }

    public Object interceptUserUpdate(ProceedingJoinPoint pjp) throws Throwable {
        /*if (CommonConstant.METHOD_UPDATE_INFO.equals(requestURI)) {*/
        Map<String, String[]> params = request.getParameterMap();
        String s = ObjectUtil.mapToString(params);
        for (Map.Entry<String, String[]> m : params.entrySet()) {
            //System.out.println("key:" + m.getKey() );
            if ("id".equals(m.getKey())) {
                for (int i = 0; i < m.getValue().length; i++) {
                    String[] value = m.getValue();
                    if (CommonConstant.PARAM_ID.equals(value[i])) {
                        System.out.println("请求参数" + s);
                        return new ResultUtil<Object>().setErrorMsg("禁止修改超级管理员信息");
                    }
                }
            }
            return interceptUserAdd(pjp);
        }
        //}
        return pjp.proceed();

    }


    public Boolean interceptContainsURI(ProceedingJoinPoint pjp, String url, String commoURI) {
        boolean flag = url.contains(commoURI);
        System.out.println(flag);
        return flag;
    }


    public Object interceptUserDeleteJudge(ProceedingJoinPoint pjp) throws Throwable {
        //先拆分url数据取得传入参数
        String[] split = requestURI.split("/");
       /* for (int i = 0; i < split.length; i++) {
            System.out.println(split[i]);
        }*/
        String[] ids = split[split.length - 1].split(",");
        for (int i = 0; i < ids.length; i++) {
            System.out.println(ids[i]);
            if (CommonConstant.PARAM_ID.equals(ids[i])) {
                return new ResultUtil<Object>().setErrorMsg("禁止删除超级管理员");
            }
        }
        return pjp.proceed();

    }

    public Object interceptRoleUpdate(ProceedingJoinPoint pjp) throws Throwable {
        Map<String, String[]> params = request.getParameterMap();
        for (Map.Entry<String, String[]> m : params.entrySet()) {
            //System.out.println("key:" + m.getKey() );
            if ("id".equals(m.getKey())) {
                for (int i = 0; i < m.getValue().length; i++) {
                    String[] value = m.getValue();
                    if (CommonConstant.PARAM_ROLEID.equals(value[i])) {
                        System.out.println("请求参数" + value[i]);
                        return new ResultUtil<Object>().setErrorMsg("禁止修改超级管理员角色信息");
                    } else if (CommonConstant.PARAM_APPROVALID.equals(value[i])) {
                        System.out.println("请求参数" + value[i]);
                        return new ResultUtil<Object>().setErrorMsg("禁止修改审批员员角色信息");
                    }
                }
            }
        }
        return pjp.proceed();
    }

    public Object interceptRoleDeleteJudge(ProceedingJoinPoint pjp) throws Throwable {

        //先拆分url数据取得传入参数
        String[] split = requestURI.split("/");
        String[] ids = split[split.length - 1].split(",");
        for (int i = 0; i < ids.length; i++) {
            System.out.println(ids[i]);
            if (CommonConstant.PARAM_APPROVALID.equals(ids[i])) {
                return new ResultUtil<Object>().setErrorMsg("禁止删除审批员角色");
            }
            if (CommonConstant.PARAM_ROLEID.equals(ids[i])) {
                return new ResultUtil<Object>().setErrorMsg("禁止删除超级管理员角色");
            }
        }

        //return new ResultUtil<Object>().setErrorMsg("禁止删除超级管理员角色");
        return pjp.proceed();
    }

    public Object interceptUserAdd(ProceedingJoinPoint pjp) throws Throwable {
        //拦截添加用户接口使系统中的超级管理员只有一个
        //1.先判断添加的用户角色是否是超级管理员
        Map<String, String[]> params = request.getParameterMap();
        for (Map.Entry<String, String[]> m : params.entrySet()) {
            //System.out.println("key:" + m.getKey() );
            if ("roles".equals(m.getKey())) {
                for (int i = 0; i < m.getValue().length; i++) {
                    String[] roles = m.getValue();
                    for (int j = 0; j < roles.length; j++) {
                        System.out.println(roles[i]);
                        if (CommonConstant.PARAM_ROLEID.equals(roles[i])) {
                            return new ResultUtil<Object>().setErrorMsg("禁止添加超级管理员用户");
                        }

                    }
                }
            }
        }
        return pjp.proceed();

    }


}
